#include "stdafx.h"
#include <iostream>
#include <fstream>
#include "Tests.h"
#include "Processor.h"
#include "OnlineStatistic.h"
#include "Sink.h"

#define BAD_ARGUMENTS 0
#define MODE_TEST 1
#define MODE_NORMAL 2

using namespace std;

void RunTests() {
	cout << "TestProcessor(): " << TestProcessor() << endl;
	cout << "TestDataReader(): " << TestDataReader() << endl;
	cout << "TestOnlineMedian(): " << TestOnlineMedian() << endl;
}

void Process(const char* inputFile, const char* outputFile) {
	FILE* pFile = NULL;
	if (!(pFile = fopen(inputFile, "r"))) {
		cout << "Missing test input file \"vidata.dat\"." << endl;
		return;
    }
	else
		fclose(pFile);
	ifstream in(inputFile, ios::binary);
	VIReader source(in, VIReader::mode_t::Current);
	ofstream out(outputFile);
	Printer<float> sink(out);
	SimpleProcessor<float, float> processor;
	OnlineMedian<float, float> onlineMedian(100000, true, 0.0f);
	processor.Run(&source, &onlineMedian, &sink);
	out.close();
	in.close();
}

int ParseArguments(int argc, char* argv[]) {
	if(
		argc < 2 || argc > 3
		|| (argc == 2 && strcmp(argv[1], "-test"))
		|| (argc == 3 && !strcmp(argv[2], "-test")))
	{
		cout << "Usage: " << argv[0] << " { inputFile outputFile } | { -test }" << endl;
		return BAD_ARGUMENTS;
	}
	if(!strcmp(argv[1], "-test"))
		return MODE_TEST;
	return MODE_NORMAL;
}

int main(int argc, char* argv[]) {
	// Check arguments
	int mode = ParseArguments(argc, argv);
	if(mode == BAD_ARGUMENTS)
		return 1;

	// Run
	time_t start;
	time_t end;
	time(&start);

	try {
		if(mode == MODE_TEST)
			RunTests();

		else if(mode == MODE_NORMAL)  // Main use case
			Process(argv[1], argv[2]);
	}
	catch(const char* pErr) {
		cout << "Exception caught: " << pErr << endl;
	}

	time(&end);
	double elapsed = difftime(end, start);
	cout << "Running time: " << elapsed << "s" << endl;
	return 0;
}

